﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

using LINQToolKit.Douban.Entities;
using LINQToolKit.Mapping;
using LINQToolKit.Processors;

namespace LINQToolKit.Douban.Processors
{
    public sealed class SubjectPropertyProcessor : PropertyProcessor
    {
        public override object FromXml(MetaProperty meta, IEnumerable<XElement> elements)
        {
            // determine if type of the subject : music, movie or book
            XNamespace ns = "http://www.w3.org/2005/Atom";
            var e = elements.First();
            var source = e.Element(ns + "id").Value;
            var subjectType = FindSubjectType(source);

            // lookup entity definition
            IMappingSource mappingSource = meta.Entity.MappingSource;
            var entityMeta = mappingSource.Entities[subjectType];
            entityMeta.AssertNull(
                subjectType.AssemblyQualifiedName, "cannot find definition for entity");
            IXmlEntityProcessor processor = null;

            if (entityMeta.Processor == null)
            {
                processor = new DoubanEntityProcessor();
            }
            else
            {
                processor = (IXmlEntityProcessor)Activator.CreateInstance(entityMeta.Processor);
            }

            return processor.ConvertOne(entityMeta, e);
        }

        private static Type FindSubjectType(string source)
        {
            source.AssertNull("source");
            Type subjectType = null;

            if (source.Contains("book"))
            {
                subjectType = typeof(Book);
            }
            else if (source.Contains("movie"))
            {
                subjectType = typeof(Movie);
            }
            else if (source.Contains("music"))
            {
                subjectType = typeof(Music);
            }
            else
            {
                throw new NotImplementedException("unkown subject type " + source);
            }

            return subjectType;
        }
    }
}
